package com.fbs.chicken.shirodemo.user.service.imp;

import com.fbs.chicken.shirodemo.user.entity.User;
import com.fbs.chicken.shirodemo.user.mapper.UserMapper;
import com.fbs.chicken.shirodemo.user.service.UserService;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationException;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.UUID;

@Service("userService")
public class UserServiceImp implements UserService {
    @Override
    public User findById(String id) {
        return userMapper.selectByPrimaryKey(id);
    }

    @Override
    public User findByName(String name) {
        return userMapper.findByName(name);
    }

    @Override
    public void login(String name, String password) {
        Subject currentUser = SecurityUtils.getSubject();

        if (!currentUser.isAuthenticated()) {
            User udb = userMapper.findByName(name);
            if (udb == null) throw new AuthorizationException("账户不存在");
            UsernamePasswordToken token = new UsernamePasswordToken(name, password);
            try {
                currentUser.login(token);

                // 更新手机盐值
                RandomNumberGenerator rng = new SecureRandomNumberGenerator();
                ByteSource salt = rng.nextBytes();
                // 将盐插入数据库
                udb.setSalt(salt.toBase64());
                String hashedPasswordBase64 = new Sha256Hash(password, salt, 1024).toBase64();
                udb.setPassword(hashedPasswordBase64);
                // TODO 更新登录时间和ip也在这里
                userMapper.updateByPrimaryKeySelective(udb);
            } catch (UnknownAccountException uae) {
                throw new AuthorizationException("There is no user with username of " + token.getPrincipal());
            } catch (IncorrectCredentialsException ice) {
                throw new AuthorizationException("Password for account " + token.getPrincipal() + " was incorrect!");
            } catch (LockedAccountException lae) {
                throw new AuthorizationException("The account for username " + token.getPrincipal() + " is locked.  " +
                        "Please contact your administrator to unlock it.");
            } catch (AuthenticationException ae) {
                // ... catch more exceptions here (maybe custom ones specific to your application?
                //unexpected condition?  error?
                ae.printStackTrace();
                throw new AuthorizationException("未知权限校验错误");
            }
            // 登录成功
        }
    }

    @Override
    public void signup(String name, String password) {
        User user = new User();
        user.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        user.setName(name);

        RandomNumberGenerator rng = new SecureRandomNumberGenerator();
        ByteSource salt = rng.nextBytes();
        // 将盐插入数据库
        user.setSalt(salt.toBase64());
        String hashedPasswordBase64 = new Sha256Hash(password, salt, 1024).toBase64();
        user.setPassword(hashedPasswordBase64);

        userMapper.insertSelective(user);
    }


    @Resource
    private UserMapper userMapper;
}
